package com.glsc.ngateway.platform.service.itflow.flowstrategy.cmdb.deviceStandardModify.taskPostHandler;

import cn.hutool.core.collection.CollectionUtil;
import com.alibaba.excel.util.CollectionUtils;
import com.glsc.ngateway.common.api.platform.dto.user.PlatformUserDto;
import com.glsc.ngateway.common.base.domain.mysql.cmdb.*;
import com.glsc.ngateway.common.base.domain.mysql.gateway.platform.flow.cmdb.*;
import com.glsc.ngateway.common.api.flowable.dto.task.doTaskParam.cmdb.CMDBPassParamDto;
import com.glsc.ngateway.common.api.flowable.dto.task.formData.cmdb.DeviceStandardModifyTaskFormDto;
import com.glsc.ngateway.common.api.flowable.dto.task.formData.cmdb.domainDto.FlowFormDeviceStandardModifyDto;
import com.glsc.ngateway.common.api.platform.dto.user.UserLeadersDto;
import com.glsc.ngateway.common.base.enums.itflow.ITFlowStatus;
import com.glsc.ngateway.common.base.repo.mysql.gateway.platform.flow.cmdb.*;
import com.glsc.ngateway.platform.service.UserService;
import com.glsc.ngateway.platform.service.cmdb.*;
import com.glsc.ngateway.platform.service.itflow.flowstrategy.AbstractHandlerHelper;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import java.util.Arrays;
import java.util.List;
import java.util.Objects;
import java.util.stream.Collectors;

import static com.glsc.ngateway.common.api.common.enums.DictConstant.CMDB_CONFIRM;

/**
 * @author liwei
 * @date 2023/8/4-13:49
 */
@Component
public class DSMStepHandlerHelper extends AbstractHandlerHelper {

    private final Logger logger = LoggerFactory.getLogger(this.getClass());
    private final String ADDTYPE = "0";
    private final String UPDATETYPE = "2";
    private final String DELETETYPE = "1";
    @Autowired
    FlowFormDeviceStandardModifyRepo flowFormDeviceStandardModifyRepo;
    @Autowired
    private FlowFormNewDeviceStandardDetailRepo flowFormNewDeviceStandardDetailRepo;
    @Autowired
    private FlowFormNewDeviceCpuStandardDetailRepo flowFormNewDeviceCpuStandardDetailRepo;
    @Autowired
    private FlowFormNewDeviceMemoryStandardDetailRepo flowFormNewDeviceMemoryStandardDetailRepo;
    @Autowired
    private FlowFormNewDeviceDiskStandardDetailRepo flowFormNewDeviceDiskStandardDetailRepo;
    @Autowired
    private FlowFormNewDevicePartStandardDetailRepo flowFormNewDevicePartStandardDetailRepo;


    @Autowired
    FlowFormNewCPUStandardDetailRepo cpuStandardNewRepo;
    @Autowired
    FlowFormNewMemoryStandardDetailRepo memoryStandardNewRepo;
    @Autowired
    FlowFormNewDiskStandardDetailRepo diskStandardNewRepo;
    @Autowired
    FlowFormNewPartStandardDetailRepo partStandardNewRepo;

    @Autowired
    private UserService userService;

    @Autowired
    CmdbCpuStandardService cmdbCpuStandardService;
    @Autowired
    CmdbDiskStandardService cmdbDiskStandardService;
    @Autowired
    CmdbMemoryStandardService cmdbMemoryStandardService;
    @Autowired
    CmdbPartStandardService cmdbPartStandardService;

    @Autowired
    private CmdbDeviceStandardService cmdbDeviceStandardService;

    @Autowired
    private CmdbCpuStandardDeviceStandardRelateService cmdbCpuStandardDeviceStandardRelateService;
    @Autowired
    private CmdbMemoryStandardDeviceStandardRelateService cmdbMemoryStandardDeviceStandardRelateService;
    @Autowired
    private CmdbDiskStandardDeviceStandardRelateService cmdbDiskStandardDeviceStandardRelateService;
    @Autowired
    private CmdbPartStandardDeviceStandardRelateService cmdbPartStandardDeviceStandardRelateService;



    protected void endTaskAfterHandle(CMDBPassParamDto<FlowFormDeviceStandardModifyDto, DeviceStandardModifyTaskFormDto> passParam, String operator) {
        //抄送给上级领导
        PlatformUserDto createUser = userService.findByUsername(operator);

        //直属领导
        UserLeadersDto userLeadersDto = userService.getDirectLeaderAndPrimaryDepartmentLeader(createUser);
        if (CollectionUtils.isEmpty(userLeadersDto.getDirectLeaders())) {
            logger.info(String.format("CMDB设备规格变更流程%c未找到直属领导信息。发起人：%s", passParam.getProcessId(), operator));
        } else {
            DeviceStandardModifyTaskFormDto data = passParam.getFlowableFormData();
            this.copyPorcess(passParam.getProcessId(), operator,
                    userLeadersDto.getDirectLeaders()
                    , String.format("【抄送】-【设备规格新增/删除流程】-【%s】", data.getProcessTitle())
                    , AbstractHandlerHelper.GATEWAY_CMDB_FLOW_URL + "deviceStandardFlowAudit?flowProcessId=" + passParam.getProcessId()
                    , String.format("申请人：" + data.getFormMainData().getFlowCreateOperatorName() +
//                            "<br/>  配件类型：" + data.getFormMainData().getPartType() +
                            "<br/>  业务类型：" + getBusinessTypeName(data.getFormMainData().getModifyType()) +
                            "<br/>  请知悉。可至国联技术服务平台内查阅相关事宜。"));
        }

    }

    private String getBusinessTypeName(String code) {
        if (Objects.isNull(code)) {
            return null;
        }
        if (code.equals("0")) {
            return "新增";
        } else if (code.equals("1")) {
            return "删除";
        } else if (code.equals("2")) {
            return "修改";
        }
        return null;
    }

    protected void updateDeviceStandard(String processId, String operator) {
        FlowFormDeviceStandardModify formMainDo = flowFormDeviceStandardModifyRepo.findByProcessId(processId);
        String modifyType = formMainDo.getModifyType();
        //更新业务表数据
        if (formMainDo.getIsClose() != 0) {
            return;
        }
        List<FlowFormNewDeviceStandardDetail> deviceList = flowFormNewDeviceStandardDetailRepo.findAllByprocessId(processId);
        List<FlowFormNewDeviceCpuStandardDetail> deviceCpuList = flowFormNewDeviceCpuStandardDetailRepo.findAllByprocessId(processId);
        List<FlowFormNewDeviceMemoryStandardDetail> deviceMemoryList = flowFormNewDeviceMemoryStandardDetailRepo.findAllByprocessId(processId);
        List<FlowFormNewDeviceDiskStandardDetail> deviceDiskList = flowFormNewDeviceDiskStandardDetailRepo.findAllByprocessId(processId);
        List<FlowFormNewDevicePartStandardDetail> devicePartList = flowFormNewDevicePartStandardDetailRepo.findAllByprocessId(processId);
        CmdbDeviceStandard deviceStandard = null;

        if (ADDTYPE.equals(modifyType)) {
            //新增
            //设备
            deviceStandard = add(deviceStandard, deviceList, deviceCpuList, deviceMemoryList, deviceDiskList, devicePartList, operator);
        } else if (UPDATETYPE.equals(modifyType)) {
            //修改
            //删除
            deviceStandard = deleteItem(deviceStandard, deviceList, deviceCpuList, deviceMemoryList, deviceDiskList, devicePartList, operator);
            //新增
            deviceStandard = add(deviceStandard, deviceList, deviceCpuList, deviceMemoryList, deviceDiskList, devicePartList, operator);
        } else if (DELETETYPE.equals(modifyType)) {
            //删除
            deviceStandard = delete(deviceStandard, deviceList, deviceCpuList, deviceMemoryList, deviceDiskList, devicePartList, operator);
        }


        //更新流程主表isClose
        formMainDo.setIsClose(1);
        formMainDo.setStatus(ITFlowStatus.END.getCode());
        flowFormDeviceStandardModifyRepo.save(formMainDo);
    }


    private CmdbDeviceStandard delete(CmdbDeviceStandard deviceStandard, List<FlowFormNewDeviceStandardDetail> deviceList, List<FlowFormNewDeviceCpuStandardDetail> deviceCpuList, List<FlowFormNewDeviceMemoryStandardDetail> deviceMemoryList,
                                      List<FlowFormNewDeviceDiskStandardDetail> deviceDiskList, List<FlowFormNewDevicePartStandardDetail> devicePartList, String operator) {
        //设备
        if (CollectionUtil.isNotEmpty(deviceList)) {
            deviceStandard = cmdbDeviceStandardService.findCmdbDeviceStandardByName(deviceList.get(0).getStandardName());
            cmdbDeviceStandardService.deleteByCodeList(Arrays.asList(deviceStandard.getDeviceStandardCode()), operator);
        }
        //cpu
        if (CollectionUtil.isNotEmpty(deviceCpuList)) {
            List<CmdbCpuStandardDeviceStandardRelate> relateList = cmdbCpuStandardDeviceStandardRelateService.listByDeviceCode(deviceStandard.getDeviceStandardCode());
            cmdbCpuStandardDeviceStandardRelateService.deleteByCodeList(relateList.stream().map(CmdbCpuStandardDeviceStandardRelate::getId).collect(Collectors.toList()), operator);
        }
        //内存
        if (CollectionUtil.isNotEmpty(deviceMemoryList)) {
            List<CmdbMemoryStandardDeviceStandardRelate> relateList = cmdbMemoryStandardDeviceStandardRelateService.listByDeviceCode(deviceStandard.getDeviceStandardCode());
            cmdbMemoryStandardDeviceStandardRelateService.deleteByCodeList(relateList.stream().map(CmdbMemoryStandardDeviceStandardRelate::getId).collect(Collectors.toList()), operator);
        }
        //硬盘
        if (CollectionUtil.isNotEmpty(deviceDiskList)) {
            List<CmdbDiskStandardDeviceStandardRelate> relateList = cmdbDiskStandardDeviceStandardRelateService.listByDeviceCode(deviceStandard.getDeviceStandardCode());
            cmdbDiskStandardDeviceStandardRelateService.deleteByCodeList(relateList.stream().map(CmdbDiskStandardDeviceStandardRelate::getId).collect(Collectors.toList()), operator);
        }
        //配件
        if (CollectionUtil.isNotEmpty(devicePartList)) {
            cmdbPartStandardDeviceStandardRelateService.deleteByCodeList(Arrays.asList(deviceStandard.getDeviceStandardCode()), operator);
        }
        return deviceStandard;
    }

    private CmdbDeviceStandard deleteItem(CmdbDeviceStandard deviceStandard, List<FlowFormNewDeviceStandardDetail> deviceList, List<FlowFormNewDeviceCpuStandardDetail> deviceCpuList, List<FlowFormNewDeviceMemoryStandardDetail> deviceMemoryList,
                                          List<FlowFormNewDeviceDiskStandardDetail> deviceDiskList, List<FlowFormNewDevicePartStandardDetail> devicePartList, String operator) {
        //设备
        if (CollectionUtil.isNotEmpty(deviceList)) {
            cmdbDeviceStandardService.deleteByCodeList(deviceList.stream().map(FlowFormNewDeviceStandardDetail::getDeviceStandardCodeFlow).collect(Collectors.toList()), operator);
        }
        //cpu
        if (CollectionUtil.isNotEmpty(deviceCpuList)) {
            cmdbCpuStandardDeviceStandardRelateService.deleteByCodeList(deviceCpuList.stream().map(FlowFormNewDeviceCpuStandardDetail::getCpuDeviceRelateId).collect(Collectors.toList()), operator);
        }
        //内存
        if (CollectionUtil.isNotEmpty(deviceMemoryList)) {
            cmdbMemoryStandardDeviceStandardRelateService.deleteByCodeList(deviceMemoryList.stream().map(FlowFormNewDeviceMemoryStandardDetail::getMemoryDeviceRelateId).collect(Collectors.toList()), operator);
        }
        //硬盘
        if (CollectionUtil.isNotEmpty(deviceDiskList)) {
            cmdbDiskStandardDeviceStandardRelateService.deleteByCodeList(deviceDiskList.stream().map(FlowFormNewDeviceDiskStandardDetail::getDiskDeviceRelateId).collect(Collectors.toList()), operator);
        }
        //配件
        if (CollectionUtil.isNotEmpty(devicePartList)) {
            cmdbPartStandardDeviceStandardRelateService.deleteByCodeList(deviceList.stream().map(FlowFormNewDeviceStandardDetail::getDeviceStandardCodeFlow).collect(Collectors.toList()), operator);
        }
        return deviceStandard;
    }


    private CmdbDeviceStandard add(CmdbDeviceStandard deviceStandard, List<FlowFormNewDeviceStandardDetail> deviceList, List<FlowFormNewDeviceCpuStandardDetail> deviceCpuList, List<FlowFormNewDeviceMemoryStandardDetail> deviceMemoryList,
                                   List<FlowFormNewDeviceDiskStandardDetail> deviceDiskList, List<FlowFormNewDevicePartStandardDetail> devicePartList, String operator) {
        if (CollectionUtil.isNotEmpty(deviceList)) {
            for (int i = 0; i < deviceList.size(); i++) {
                FlowFormNewDeviceStandardDetail deviceStandardDetail = deviceList.get(i);
                deviceStandard = CmdbDeviceStandard.builder().brand(deviceStandardDetail.getBrand()).cpuPortAmount(deviceStandardDetail.getCpuPortAmount()).diskPortAmount(deviceStandardDetail.getDiskPortAmount())
                        .elePortAmount(deviceStandardDetail.getElePortAmount()).isDelete(0).memoryPortAmount(deviceStandardDetail.getMemoryPortAmount()).model(deviceStandardDetail.getModel())
                        .pciPortAmount(deviceStandardDetail.getPciPortAmount()).standardName(deviceStandardDetail.getStandardName()).uAmount(deviceStandardDetail.getUAmount()).build();
                deviceStandard = cmdbDeviceStandardService.addOrUpdate(deviceStandard, operator,CMDB_CONFIRM);
            }
        }
        //cpu
        if (CollectionUtil.isNotEmpty(deviceCpuList)) {
            for (int i = 0; i < deviceCpuList.size(); i++) {
                FlowFormNewDeviceCpuStandardDetail cpuStandardDetail = deviceCpuList.get(0);
                CmdbCpuStandard cpuStandard = cmdbCpuStandardService.findCmdbCpuStandardByName(cpuStandardDetail.getCpuStandardName());
                CmdbCpuStandardDeviceStandardRelate cpuRelate = CmdbCpuStandardDeviceStandardRelate.builder()
                        .isDelete(0).deviceStandardCode(deviceStandard.getDeviceStandardCode()).cpuStandardCode(cpuStandard.getCpuStandardCode()).amount(cpuStandardDetail.getCpuAmount()).build();
                cmdbCpuStandardDeviceStandardRelateService.addOrUpdate(cpuRelate, operator);
            }
        }
        //内存
        if (CollectionUtil.isNotEmpty(deviceMemoryList)) {
            for (FlowFormNewDeviceMemoryStandardDetail e : deviceMemoryList) {
                CmdbMemoryStandard memoryStandard = cmdbMemoryStandardService.findCmdbMemoryStandardByName(e.getMemoryStandardName());
                CmdbMemoryStandardDeviceStandardRelate memoryRelate = CmdbMemoryStandardDeviceStandardRelate.builder()
                        .isDelete(0).deviceStandardCode(deviceStandard.getDeviceStandardCode()).memoryStandardCode(memoryStandard.getMemoryStandardCode()).amount(e.getMemoryAmount()).build();
                cmdbMemoryStandardDeviceStandardRelateService.addOrUpdateMemoryStandardDeviceStandardRelate(memoryRelate, operator);
            }
        }
        //硬盘
        if (CollectionUtil.isNotEmpty(deviceDiskList)) {
            for (FlowFormNewDeviceDiskStandardDetail e : deviceDiskList) {
                CmdbDiskStandard diskStandard = cmdbDiskStandardService.findCmdbDiskStandardByName(e.getDiskStandardName());
                CmdbDiskStandardDeviceStandardRelate diskRelate = CmdbDiskStandardDeviceStandardRelate.builder()
                        .isDelete(0).deviceStandardCode(deviceStandard.getDeviceStandardCode()).diskStandardCode(diskStandard.getDiskStandardCode()).amount(e.getAmount()).build();
                cmdbDiskStandardDeviceStandardRelateService.addOrUpdateDiskStandardDeviceStandardRelate(diskRelate, operator);
            }
        }
        //配件
        if (CollectionUtil.isNotEmpty(devicePartList)) {
            for (FlowFormNewDevicePartStandardDetail e : devicePartList) {
                CmdbPartStandard partStandard = cmdbPartStandardService.findCmdbPartStandardByName(e.getPartStandardName());
                CmdbPartStandardDeviceStandardRelate partRelate = CmdbPartStandardDeviceStandardRelate.builder()
                        .isDelete(0).deviceStandardCode(deviceStandard.getDeviceStandardCode()).partStandardCode(partStandard.getPartStandardCode()).amount(e.getAmount()).build();
                cmdbPartStandardDeviceStandardRelateService.addOrUpdatePartStandardDeviceStandardRelate(partRelate, operator);
            }
        }
        return deviceStandard;
    }
}
